/**
 * 
 */
package com.czmh.etc.onlinepubsys.services.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.czmh.etc.common.core.utils.Sequence;
import com.czmh.etc.common.core.utils.UUIDGenerator;
import com.czmh.etc.onlinepubsys.constants.QrCodeConstants;
import com.czmh.etc.onlinepubsys.dto.QrCodePromoterDto;
import com.czmh.etc.onlinepubsys.json.JsonResult;
import com.czmh.etc.onlinepubsys.maper.QrCodeMapper;
import com.czmh.etc.onlinepubsys.maper.QrCodePromoterMapper;
import com.czmh.etc.onlinepubsys.maper.QrPromotersMapper;
import com.czmh.etc.onlinepubsys.maper.QrScanRecordMapper;
import com.czmh.etc.onlinepubsys.model.EtcUser;
import com.czmh.etc.onlinepubsys.model.QrCode;
import com.czmh.etc.onlinepubsys.model.QrCodePromoter;
import com.czmh.etc.onlinepubsys.model.QrPromoters;
import com.czmh.etc.onlinepubsys.model.QrScanRecord;
import com.czmh.etc.onlinepubsys.services.QrCodePromoterService;
import com.czmh.etc.onlinepubsys.utils.JsonResultUtil;

import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket;

/**
 * @描述：二维码推广service
 * @author： Seven.
 * @创建日期：Nov 13, 2019 3:52:21 PM.
 * @版本：1.0.0
 */
@Service
@Slf4j
@Transactional(noRollbackFor = Exception.class)
public class QrCodePromoterServiceImpl implements QrCodePromoterService {
    @Autowired
    private QrCodeMapper qrCodeMapper;
    @Autowired
    private QrCodePromoterMapper qrCodePromoterMapper;
    @Autowired
    private QrPromotersMapper qrPromotersMapper;
    @Autowired
    private QrScanRecordMapper qrScanRecordMapper;
    @Autowired
    private WxMpService wxMpService;
    
    @Override
    public JsonResult createQrcode(String userId, String mblNo) throws WxErrorException {
        Map<String, String> data = new HashMap<String, String>();
        // 1.查询推广员手机号是否存在，存在则生成二维码
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("promoter_phone", mblNo);
        List<QrPromoters> list = qrPromotersMapper.getAll(params);
        if (!list.isEmpty()) {
            // 查询该用户手机号是否已生成过一级推广二维码
            QrCodePromoterDto level1Code = qrCodeMapper.getQrCodeByPromoterphone(mblNo);
            if (level1Code == null) {
                // 2.生成二维码
                String scene = QrCodeConstants.QR_LEVEL_1 + UUIDGenerator.getUUID();
                WxMpQrCodeTicket ticket = wxMpService.getQrcodeService().qrCodeCreateLastTicket(scene);
                QrPromoters qrPromoters = list.get(0);
                String promoterid = qrPromoters.getPromoterid();
                QrCode qrcode = new QrCode(Sequence.getId());
                qrcode.setImgurl("https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" + ticket.getTicket());
                qrcode.setType(2);
                qrcode.setRestype(2);
                qrcode.setRemark("一级推广员");
                qrcode.setStatus(true);
                qrcode.setScene(scene);
                qrcode.setTicket(ticket.getTicket());
                qrcode.setQrurl(ticket.getUrl());
                qrcode.setCreatetime(new Date());
                qrcode.setUpdatetime(new Date());
                qrCodeMapper.insert(qrcode);
                QrCodePromoter qrcodePromoter = new QrCodePromoter(Sequence.getId());
                qrcodePromoter.setPromoterid(promoterid);
                qrcodePromoter.setQrid(qrcode.getQrid());
                qrcodePromoter.setCreatetime(new Date());
                qrCodePromoterMapper.insert(qrcodePromoter);
                QrPromoters update = new QrPromoters(promoterid);
                update.setUser_id(userId);
                qrPromotersMapper.update(update);
                data.put("url", ticket.getUrl());
                log.info(String.format("[新增推广员二维码] 推广员手机号：\"%s\"", mblNo));
                return JsonResultUtil.toResult(data);
            } else {
                data.put("url", level1Code.getQrurl());
                log.info(String.format("[该用户手机号已有推广码] 手机号：\"%s\"", mblNo));
                return JsonResultUtil.toResult(data);
            }
        } else {
            log.info(String.format("[没有查找到该用户手机号的推广员] 手机号：\"%s\"", mblNo));
            return JsonResultUtil.toErrorResult("没有查找到该用户手机号的推广员");
        }
    }

    @Override
    public Map<String, String> bindPromoter(EtcUser etcUser, String scene) throws WxErrorException {
        // 定义返回结果
        String url = "";
        String phone = "";
        Map<String, String> map = new HashMap<String, String>();
        // 查询场景值二维码是否存在
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("scene", scene);
        List<QrCode> list = qrCodeMapper.getAll(params);
        if (!list.isEmpty()) {
            QrCode qrCode = list.get(0);
            params.clear();
            params.put("qrid", qrCode.getQrid());
            // 获取该二维码是否绑定了推广员
            List<QrCodePromoter> list2 = qrCodePromoterMapper.getAll(params);
            if (!list2.isEmpty()) {
                // 查询【当前扫码用户】是否已经生成过推广码
                QrCodePromoterDto promoterQrCode = qrCodeMapper.getQrCodeByUserId(etcUser.getUser_id());
                if (promoterQrCode == null) {
                    // 生成二级推广码
                    String scene2 = QrCodeConstants.QR_LEVEL_2 + UUIDGenerator.getUUID();
                    WxMpQrCodeTicket ticket = wxMpService.getQrcodeService().qrCodeCreateLastTicket(scene2);
                    // 获取一级推广员id
                    QrCodePromoter qrCodePromoter = list2.get(0);
                    String promoterid = qrCodePromoter.getPromoterid();
                    QrPromoters parentPromoter = qrPromotersMapper.getById(promoterid);
                    phone = parentPromoter.getPromoter_phone();
                    QrPromoters qrPromoter = new QrPromoters(Sequence.getId());
                    qrPromoter.setParent_id(promoterid);
                    qrPromoter.setUser_id(etcUser.getUser_id());
                    qrPromoter.setCreatetime(new Date());
                    qrPromoter.setUpdatetime(new Date());
                    // 新增二级推广员
                    qrPromotersMapper.insert(qrPromoter);
                    // 新增二级推广员二维码
                    QrCode qrcode = new QrCode(Sequence.getId());
                    url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" + ticket.getTicket();
                    qrcode.setImgurl(url);
                    qrcode.setType(2);
                    qrcode.setRestype(2);
                    qrcode.setRemark("二级推广员");
                    qrcode.setStatus(true);
                    qrcode.setScene(scene2);
                    qrcode.setTicket(ticket.getTicket());
                    qrcode.setQrurl(ticket.getUrl());
                    qrcode.setCreatetime(new Date());
                    qrcode.setUpdatetime(new Date());
                    qrCodeMapper.insert(qrcode);
                    QrCodePromoter qrcodePromoter = new QrCodePromoter(Sequence.getId());
                    qrcodePromoter.setPromoterid(qrPromoter.getPromoterid());
                    qrcodePromoter.setQrid(qrcode.getQrid());
                    qrcodePromoter.setCreatetime(new Date());
                    // 绑定二维码与推广员关联关系
                    qrCodePromoterMapper.insert(qrcodePromoter);
                    map.put("url", url);
                    map.put("phone", phone);
                    map.put("isNew", "new");
                    log.info(String.format("[生成二级二维码] 推广员id：\"%s\" 二维码图片：\"%s\"", qrPromoter.getPromoterid(), "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" + ticket.getTicket()));
                } else {
                    url = promoterQrCode.getQrurl();
                    // 如果存在上级推广员则获取上级推广员的手机号上级推广员手机号
                    if (StringUtils.isNotEmpty(promoterQrCode.getParent_id())) {
                        QrPromoters parentPromoter = qrPromotersMapper.getById(promoterQrCode.getParent_id());
                        phone = parentPromoter.getPromoter_phone();
                    }
                    map.put("url", url);
                    map.put("phone", phone);
                }
            } else {
                log.error(String.format("[该二维码没有绑定一级推广员] 二维码场景值：\"%s\"", scene));
            }
        } else {
            log.error(String.format("[不存在该场景二维码] 二维码场景值：\"%s\"", scene));
        }
        // 2.添加扫码记录
        this.addQrScanRecord(etcUser, scene);
        return map;
    }

    @Override
    public void addQrScanRecord(EtcUser etcUser, String scene) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("scene", scene);
        // 查询该场景二维码是否存在
        List<QrCode> list = qrCodeMapper.getAll(params);
        if (!list.isEmpty()) {
            QrCode qrCode = list.get(0);
            params.clear();
            params.put("user_id", etcUser.getUser_id());
            params.put("qrid", qrCode.getQrid());
            Long count = qrScanRecordMapper.count(params);
            // 根据用户id和二维码id查询该用户是否已经扫描过该二维码了，如果没有扫描过则新增扫码记录
            if (count == 0) {
                // 查询扫码用户是不是系统的推广员
                QrCodePromoterDto promoterQrCode = qrCodeMapper.getQrCodeByUserId(etcUser.getUser_id());
                if (promoterQrCode != null && promoterQrCode.getParent_id() == null) {
                    // 扫码用户是是推广员并且是一级推广员，则不增加扫码记录
                    log.info(String.format("[扫码用户是是推广员并且是一级推广员，则不增加扫码记录] 用户id：\"%s\" 二维码id：\"%s\"", etcUser.getUser_id(), qrCode.getQrid()));
                } else if (promoterQrCode != null && promoterQrCode.getParent_id() != null) {
                    // 扫码用户是是推广员并且是二级推广员，则判断本次扫描的二维码id和用户的推广二维码id是否一致，如果一致则不增加扫码记录(自己扫自己二维码不增加)
                    if (!qrCode.getQrid().equals(promoterQrCode.getQrid())) {
                        params.clear();
                        params.put("user_id", etcUser.getUser_id());
                        count = qrScanRecordMapper.count(params);
                        if (count == 0) {
                            addScan(etcUser, qrCode);
                        }
                        log.info(String.format("[扫码用户是是推广员并且是二级推广员，则判断本次扫描的二维码id和用户的推广二维码id是否一致，如果一致则不增加扫码记录(自己扫自己二维码不增加)] 用户id：\"%s\" 二维码id：\"%s\"", etcUser.getUser_id(), qrCode.getQrid()));
                    }
                } else {
                    // 普通引流用户则要判断是否有扫描过其他推广员的二维码，如果没有则增加扫码记录
                    params.clear();
                    params.put("user_id", etcUser.getUser_id());
                    count = qrScanRecordMapper.count(params);
                    if (count == 0) {
                        addScan(etcUser, qrCode);
                    }
                    log.info(String.format("[普通引流用户则要判断是否有扫描过其他推广员的二维码，如果没有则增加扫码记录] 用户id：\"%s\" 二维码id：\"%s\"", etcUser.getUser_id(), qrCode.getQrid()));
                }
                
            } else {
                log.info(String.format("[用户扫码已扫过该二维码] 用户id：\"%s\" 二维码id：\"%s\"", etcUser.getUser_id(), qrCode.getQrid()));
            }
        }
    }

    private void addScan(EtcUser etcUser, QrCode qrCode) {
        QrScanRecord scanRecord = new QrScanRecord(Sequence.getId());
        scanRecord.setQrid(qrCode.getQrid());
        scanRecord.setUser_id(etcUser.getUser_id());
        scanRecord.setCreatetime(new Date());
        qrScanRecordMapper.insert(scanRecord);
        log.info(String.format("[用户扫码] 用户id：\"%s\" 二维码id：\"%s\"", etcUser.getUser_id(), qrCode.getQrid()));
    }

    @Override
    public JsonResult qrCode(String userId) {
        QrCodePromoterDto codePromoterDto = qrCodeMapper.getQrCodeByUserId(userId);
        return JsonResultUtil.toResult(codePromoterDto);
    }
}
